package com.winit.openapi.fsp.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.SearchOperator;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.query.filter.SearchFilterHelper;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.fsp.spi.common.Constant.LoansStatusEnum;
import com.winit.fsp.spi.loans.LoanContractService;
import com.winit.fsp.spi.loans.LoanService;
import com.winit.fsp.spi.loans.command.CountLoanByPartnerIdCommand;
import com.winit.fsp.spi.loans.command.CreateLoanCommand;
import com.winit.fsp.spi.loans.command.DeleteLoanLineCommand;
import com.winit.fsp.spi.loans.command.GetLoanByIdCommand;
import com.winit.fsp.spi.loans.command.GetLoanBySupplierIdCommand;
import com.winit.fsp.spi.loans.command.GetLoanContractByLoanIdCommand;
import com.winit.fsp.spi.loans.command.GetLoanLinesByLoanIdCommand;
import com.winit.fsp.spi.loans.command.GetStockInLoanLineCommand;
import com.winit.fsp.spi.loans.command.GetWaitPayLoanCommand;
import com.winit.fsp.spi.loans.command.QueryLoanCommand;
import com.winit.fsp.spi.loans.command.ReApplyLoanCommand;
import com.winit.fsp.spi.loans.command.UpdateLoanCommand;
import com.winit.fsp.spi.loans.command.VoidLoanCommand;
import com.winit.fsp.spi.loans.vo.Loan;
import com.winit.fsp.spi.loans.vo.LoanContract;
import com.winit.fsp.spi.loans.vo.LoanLine;
import com.winit.fsp.spi.loans.vo.LoanStatus;
import com.winit.mms.spi.goods.GoodsService;
import com.winit.mms.spi.goods.command.GetGoodsByGoodsIdCommand;
import com.winit.mms.spi.goods.vo.Goods;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.ValidateUtil;

/**
 * FSP 贷款单
 * 
 * @version <pre>
 * Author   Version     Date        Changes
 * hui.li2  1.0         2015-3-10   Created
 * 
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "/fsp/loans")
public class LoanController extends BaseController {

    @Resource
    private LoanService loanService;
    
    @Resource
    private GoodsService goodsService;
    
    @Resource
    private LoanContractService loanContractService;

    /**
     * 创建fsp贷款单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createLoans")
    public String createLoans(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        CreateLoanCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            try {
            command = JSONObject.parseObject(json.toJSONString(), CreateLoanCommand.class);
            } catch (Exception e) {
                throw new ApiException(ErrorCode.ILLEGAL_JSON_STRING, e.getMessage());
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        CommandContext ctx = CommandContext.getContext();
        Bpartner bpartner = (Bpartner) ctx.get(ApiConstant.API_BPARTNER);
        command.setPartnerId(bpartner.getcBpartnerId().intValue());
        loanService.createLoans(command);
        return SUCCESS;
    }

    /**
     * 修改fsp贷款单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updateLoans")
    public String updateLoans(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        UpdateLoanCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildUpdateLoansCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        loanService.updateLoans(command);
        return SUCCESS;
    }

    /**
     * 作废fsp贷款单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/voidLoans")
    public String voidLoans(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        VoidLoanCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildDeleteLoansCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        loanService.voidLoans(command);
        return SUCCESS;
    }

    /**
     * 重新申请fsp贷款单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/reApplyLoans")
    public String reApplyLoans(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        ReApplyLoanCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildReApplyLoansCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        loanService.reApplyLoans(command);
        return SUCCESS;
    }

    /**
     * 分页查询fsp贷款单列表信息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/pageQueryLoans")
    public String pageQueryLoans(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        QueryLoanCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validpageParams(json);
            command = new QueryLoanCommand();
            Searchable searchable = buildSearchPageParams(json);
            command.setSearchable(searchable);
        } else if (obj == null || StringUtils.isBlank(obj.toString())) {
            Searchable searchable = buildSearchPageParams(null);
            command = new QueryLoanCommand();
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        // 调用接口分页查询订单
        Page<Loan> pagelist = loanService.queryLoans(command);
        if (pagelist != null) {
            if (pagelist.getContent() != null && pagelist.getContent().size() != 0) {
                for (int i = 0; i < pagelist.getContent().size(); i++) {
                    GetLoanContractByLoanIdCommand lcCommand = new GetLoanContractByLoanIdCommand();
                    lcCommand.setLoansId(pagelist.getContent().get(i).getLoanId());
                    LoanContract lc = loanContractService.getLoanContractByLoanId(lcCommand);
                    if (lc != null) {
                        pagelist.getContent().get(i).setInterestRate(lc.getLoanPlan().getMonthlyRate());
                    }
                }
            }
            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber() + 1);
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", pagelist.getContent());
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }

        return SUCCESS;
    }

    /**
     * 查询fsp贷款单 详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getLoansById")
    public String getLoansById(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        GetLoanByIdCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildQueryLoansCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        Loan loans = loanService.getLoansById(command);
        responseMsg.setData(loans);
        return SUCCESS;
    }

    /**
     * 根据供应商获取fsp贷款单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getLoansBySupplierId")
    public String getLoansBySupplierId(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        GetLoanBySupplierIdCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildGetLoansBySupplierIdCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        List<Loan> list = loanService.getLoansBySupplierId(command);
        responseMsg.setData(list);
        return SUCCESS;
    }

    /**
     * 获取fsp贷款单所有状态
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getAllLoansStatus")
    public String getAllLoansStatus(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        List<LoanStatus> list = loanService.getAllLoansStatus();
        responseMsg.setData(list);
        return SUCCESS;
    }

    @RequestMapping(value = "/getLoansLineByLoansId")
    public String getLoansLineByLoansId(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        GetLoanLinesByLoanIdCommand command = new GetLoanLinesByLoanIdCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            if (json.containsKey("fspLoansId")) {
                command.setFspLoansId(json.getLongValue("fspLoansId"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        List<LoanLine> loansLines = loanService.getLoansLinesByLoansId(command);
        if(loansLines != null){
            for (LoanLine loansLine : loansLines) {
                GetGoodsByGoodsIdCommand gc = new GetGoodsByGoodsIdCommand();
                gc.setGoodsId(loansLine.getGoodId());
                Goods goods =  this.goodsService.getGoodsByGoodsId(gc);
                if(goods != null ){
                    loansLine.setGoodsStatus(goods.getReviewStatus());
                    loansLine.setGoodsRemark(goods.getSuggestion());
                }
            }
        }
        responseMsg.setData(loansLines);
        return SUCCESS;
    }

    
    @RequestMapping(value = "/getStockInLoansLine")
    public String getStockInLoansLine(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        GetStockInLoanLineCommand command = new GetStockInLoanLineCommand();
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = JSONObject.parseObject(json.toJSONString(),GetStockInLoanLineCommand.class);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        List<LoanLine> list = loanService.getStockInLoansLine(command);
        responseMsg.setData(list);
        return SUCCESS;
    }
 
    /**
     *  获取待支付货款单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getWaitPayLoan")
    public String getWaitPayLoan(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        GetWaitPayLoanCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = new GetWaitPayLoanCommand();
            if (json.containsKey("partnerId")) {
                command.setPartnerId(json.getInteger("partnerId"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        List<Loan> loans = loanService.getWaitPayLoan(command);
        responseMsg.setData(loans);
        return SUCCESS;
    }
    
    /**
     * 删除fsp贷款单产品
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/deleteLoansLine")
    public String deleteLoansLine(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        DeleteLoanLineCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = buildDeleteLoansLineCommand(json);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        loanService.deleteLoansLine(command);
        return SUCCESS;
    }
 
    /**
     * 删除fsp贷款单产品
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/isExistLoan")
    public String isExistLoan(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        CountLoanByPartnerIdCommand command=new CountLoanByPartnerIdCommand();
        CommandContext ctx = CommandContext.getContext();
        Bpartner bpartner = (Bpartner) ctx.get(ApiConstant.API_BPARTNER);
        command.setPartnerId(bpartner.getcBpartnerId());
        int count=loanService.countLoanByPartnerId(command);
        Map<String, Object> data = new HashMap<String, Object>();
        if(count!=0){
            data.put("flag", true);
        }else{
            data.put("flag", false); 
        }
        responseMsg.setData(data);
        return SUCCESS;
    }
     

    private void validpageParams(JSONObject json) {
        // pageParams
        if (json.containsKey("pageParams")) {
            Object obj = json.get("pageParams");
            if (obj instanceof JSONObject) {
                JSONObject pageParams = (JSONObject) obj;
                // pageNo
                ValidateUtil.validInteger(pageParams, "pageNo");

                // pageSize
                ValidateUtil.validInteger(pageParams, "pageSize");

                if (pageParams.containsKey("pageNo")) {
                    int pageNo = pageParams.getInteger("pageNo");
                    if (pageNo < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
                    }
                }
                if (pageParams.containsKey("pageSize")) {
                    int pageSize = pageParams.getInteger("pageSize");
                    if (pageSize < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                    }
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageParams");
            }
        }
    }

    private Searchable buildSearchPageParams(JSONObject json) {
        int pageNo = ApiConstant.PAGE_NO_DEFAULT;
        int pageSize = ApiConstant.PAGE_SIZE_DEFAULT;
        // pageParams
        if (json != null && json.containsKey("pageParams")) {
            JSONObject pageParams = json.getJSONObject("pageParams");
            // pageNo
            if (pageParams.containsKey("pageNo")) {
                pageNo = pageParams.getInteger("pageNo");
            }
            // pageSize
            if (pageParams.containsKey("pageSize")) {
                pageSize = pageParams.getInteger("pageSize");
            }
        }
        Searchable search = Searchable.newSearchable();
        search.setPage(pageNo - 1, pageSize);
        if (null != json && json.containsKey("status")) {
            if("applying".equalsIgnoreCase(json.getString("status"))){
                List<String> where = new ArrayList<String>();
                where.add("'" + LoansStatusEnum.WAP.getVal() + "'");
                where.add("'" + LoansStatusEnum.APD.getVal() + "'");
                where.add("'" + LoansStatusEnum.RJD.getVal() + "'");
                where.add("'" + LoansStatusEnum.WSG.getVal() + "'");
                where.add("'" + LoansStatusEnum.EFT.getVal() + "'");
                where.add("'" + LoansStatusEnum.CSD.getVal() + "'");
                search.and(SearchFilterHelper.newCondition("STATUS", SearchOperator.in, "( " + StringUtils.join(where,",") + " )"));
            }else if("repayment".equalsIgnoreCase(json.getString("status"))){
                search.and(SearchFilterHelper.newCondition("STATUS", SearchOperator.eq, LoansStatusEnum.SRP.getVal()));
            } 
        }
        if (null != json && json.containsKey("partnerId")) {
            search.and(SearchFilterHelper.newCondition("PARTNER_ID", SearchOperator.eq, json.get("partnerId")));
        }
        search.addSort(new Sort(Direction.DESC, "CREATED"));
        return search;
    }
    
    /**
     * 封装禁用贷款单明细命令
     * 
     * @param json
     * @return
     */
    private VoidLoanCommand buildDeleteLoansCommand(JSONObject json) {
        VoidLoanCommand command = new VoidLoanCommand();
        if (json.containsKey("fspLoansId")) {
            command.setLoanId(json.getLongValue("fspLoansId"));
        }
        return command;
    }

    /**
     * 封装查看贷款单明细命令
     * 
     * @param json
     * @return
     */
    private GetLoanByIdCommand buildQueryLoansCommand(JSONObject json) {
        GetLoanByIdCommand command = new GetLoanByIdCommand();
        if (json.containsKey("fspLoansId")) {
            command.setFspLoansId(json.getIntValue("fspLoansId"));
        }
        return command;
    }

    /**
     * 封装根据供应商获取贷款单命令
     * 
     * @param json
     * @return
     */
    private GetLoanBySupplierIdCommand buildGetLoansBySupplierIdCommand(JSONObject json) {
        GetLoanBySupplierIdCommand command = new GetLoanBySupplierIdCommand();
        if (json.containsKey("supplierId")) {
            command.setSupplierId(json.getLongValue("supplierId"));
        }
        return command;
    }

    /**
     * 封装修改贷款单命令
     * 
     * @param json
     * @return
     */
    private UpdateLoanCommand buildUpdateLoansCommand(JSONObject json) {
        UpdateLoanCommand command = new UpdateLoanCommand();
        if (json.containsKey("fspLoansId")) {
            command.setLoanId(json.getLongValue("fspLoansId"));
        }

        if (json.containsKey("partnerId")) {
            command.setPartnerId(json.getIntValue("partnerId"));
        }

        if (json.containsKey("fspSupplierId")) {
            command.setSupplierId(json.getIntValue("fspSupplierId"));
        }

        return command;
    }

    /**
     * 封装重新申请贷款单命令
     * 
     * @param json
     * @return
     */
    private ReApplyLoanCommand buildReApplyLoansCommand(JSONObject json) {
        ReApplyLoanCommand command = new ReApplyLoanCommand();
        if (json.containsKey("fspLoansId")) {
            command.setFspLoansId(json.getLongValue("fspLoansId"));
        }
        if (json.containsKey("loansLinesIds")) {
            JSONArray arrays = json.getJSONArray("loansLinesIds");
            List<Long> ids = new ArrayList<Long>();
            if(arrays != null && !arrays.isEmpty()){
                for (int j = 0; j < arrays.size(); j++) {
                    ids.add(arrays.getLong(j));
                }
            }
            command.setLoansLinesIds(ids);
        }
        return command;
    }

    /**
     * 封装删除贷款单产品命令
     * 
     * @param json
     * @return
     */
    private DeleteLoanLineCommand buildDeleteLoansLineCommand(JSONObject json) {
        DeleteLoanLineCommand command = new DeleteLoanLineCommand();
        if (json.containsKey("fspLoansLineId")) {
            command.setFspLoansLineId(json.getLongValue("fspLoansLineId"));
        }
        return command;
    }

}
